package org.behrang.macbeans.tab.coda;

import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.GradientPaint;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.Rectangle2D;
import java.net.URL;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JComponent;
import javax.swing.plaf.ComponentUI;
import org.netbeans.swing.tabcontrol.TabDisplayer;
import org.netbeans.swing.tabcontrol.plaf.AbstractViewTabDisplayerUI;
import org.netbeans.swing.tabcontrol.plaf.TabControlButton;
import org.openide.awt.HtmlRenderer;

/**
 *
 * @author Behrang Saeedzadeh <behrangsa@gmail.com>
 */
public class CodaViewTabDisplayerUI extends AbstractViewTabDisplayerUI {

    public static final Color TOP = new Color(64, 64, 64);
    public static final Color SIDE = new Color(170, 170, 170);
    public static final Color BG_TOP = new Color(237, 237, 237);
    public static final Color BG_BOTTOM = new Color(210, 210, 210);

    public static final Color SBG_TOP = new Color(145, 216, 247);
    public static final Color SBG_BOTTOM = new Color(89, 152, 225);

    private static final int TXT_X_PAD = 5;
    private static final int ICON_X_PAD = 2;
    
    public static ComponentUI createUI(JComponent c) {
        return new CodaViewTabDisplayerUI((TabDisplayer) c);
    }
    
    public CodaViewTabDisplayerUI(TabDisplayer displayer) {
        super(displayer);
    }
    
    @Override
    protected void paintTabBackground(Graphics g, int index, int x, int y, int width, int height) {    
        if (isSelected(index)) {
            paintSelectedBackground(g, index, x, y, width, height);
        } else {
            paintNormalBackground(g, index, x, y, width, height);
        }
    }
    
    private void paintNormalBackground(Graphics gr, int index, int x, int y, int width, int height) {            
        Graphics2D g = (Graphics2D) gr;
        GradientPaint gp 
                = new GradientPaint(x, y, BG_TOP, x, y + height, BG_BOTTOM);            
        Rectangle2D bg = new Rectangle2D.Double(x + 1, y + 1, width - 1, height - 1);
        g.setPaint(gp);
        g.fill(bg);
    }
    
    private void paintSelectedBackground(Graphics gr, int index, int x, int y, int width, int height) {            
        Graphics2D g = (Graphics2D) gr;
        GradientPaint gp 
                = new GradientPaint(x, y + 1, SBG_TOP, x, y + height - 2, SBG_BOTTOM);            
        Rectangle2D bg = new Rectangle2D.Double(x + 1, y + 1, width - 1, height - 2);
        g.setPaint(gp);
        g.fill(bg);
    }
        

    @Override
    protected void paintTabBorder(Graphics g, int index, int x, int y, int width, int height) {
        g.setColor(TOP);
        g.drawLine(x, y, x + width, y);

        g.setColor(SIDE);
        g.drawLine(x, y + 1, x, y + height);            
        g.drawLine(x, y + height - 1, x + width, y + height - 1);
    }

    @Override
    protected void paintTabContent(Graphics g, int index, String text,
        int x, int y, int width,
        int height) {

        FontMetrics fm = getTxtFontMetrics();
        
        // setting font already here to compute string width correctly
        Font font = getTextFont(isSelected(index));
        g.setFont(font);
        int textW = width;

        if (isSelected(index)) {
            Component buttons = getControlButtons();
            if( null != buttons ) {
                Dimension buttonsSize = buttons.getPreferredSize();

                textW = width - (buttonsSize.width + ICON_X_PAD + 2*TXT_X_PAD);
                if (index == getDataModel().size() - 1) {
                    textW -= 3;
                }
                buttons.setLocation( x + textW+2*TXT_X_PAD, y + (height-buttonsSize.height)/2 );
            }
        } else {
            textW = width - 2 * TXT_X_PAD;
        }

        if (text.length() == 0) {
            return;
        }

        int textHeight = fm.getHeight();
        int textY;
        int textX = x + TXT_X_PAD;
	if (index == 0)
	    textX = x + 5;

        if (textHeight > height) {
            textY = (-1 * ((textHeight - height) / 2)) + fm.getAscent()
                    - 1;
        } else {
            textY = (height / 2) - (textHeight / 2) + fm.getAscent();
        }

        Color color = isSelected(index) ? CodaColors.SELECTED_VIEW_TAB_TEXT : CodaColors.NORMAL_VIEW_TAB_TEXT;
        HtmlRenderer.renderString(text, g, textX, textY, textW, height, font,
                          color, HtmlRenderer.STYLE_TRUNCATE, true);
    }
    
    @Override
    public Dimension getPreferredSize(JComponent c) {
        return new Dimension(100, 20);
    }
    
    public Font getTextFont(boolean selected) {
        if (selected) {
            return getTxtFont().deriveFont(Font.BOLD);
        }
        return getTxtFont();
    }
    
    @Override
    public Icon getButtonIcon(int buttonId, int buttonState) {
        URL slideLeftUrl = getClass().getResource("resources/tab_slide_left.png");
        URL slideRightUrl = getClass().getResource("resources/tab_slide_right.png");
        URL slideBottomUrl = getClass().getResource("resources/tab_slide_bottom.png");
        URL pinUrl = getClass().getResource("resources/tab_pin.png");
        URL closeUrl = getClass().getResource("resources/tab_close.png");        
        switch (buttonId) {
            case TabControlButton.ID_CLOSE_BUTTON:
                return new ImageIcon(closeUrl);
            case TabControlButton.ID_SLIDE_LEFT_BUTTON:
                return new ImageIcon(slideLeftUrl);
            case TabControlButton.ID_SLIDE_RIGHT_BUTTON:
                return new ImageIcon(slideRightUrl);
            case TabControlButton.ID_SLIDE_DOWN_BUTTON:
                return new ImageIcon(slideBottomUrl);
            case TabControlButton.ID_PIN_BUTTON:
                return new ImageIcon(pinUrl);
            default:
                return null;
        }
    }
}
